
#include "SysConfig.h"
#include "Define.h"
#include "Port.h"
#include "Model_Option.h"

#define	BMASK_0		0x01
#define	BMASK_1		0x02
#define	BMASK_2		0x04
#define	BMASK_3		0x05
#define	BMASK_4		0x10
#define	BMASK_5		0x20
#define	BMASK_6		0x40
#define	BMASK_7		0x80

#define	AD_CH0		0x00
#define	AD_CH1		0x01
#define	AD_CH2		0x02
#define	AD_CH3		0x03
#define	AD_CH4		0x04
#define	AD_CH5		0x05
#define	AD_CH6		0x06
#define	AD_CH7		0x07

#ifdef  MODEL_AGC5030
#define	AD_RMC		AD_CH2
#define	AD_BAT		AD_CH6
#define	AD_AUX		AD_CH5
#endif
#ifdef  MODEL_AGC505X
#define	AD_RMC		AD_CH2
#define	AD_BAT		AD_CH6
#define	AD_AUX		AD_CH5
#endif
#ifdef  MODEL_ARA5040
#define	AD_RMC		AD_CH1
#define	AD_BAT		AD_CH3
#define	AD_AUX		AD_CH4
#endif

unsigned char ucCPU_ADC_Sequence;
unsigned short usCPU_ADC_Rmc;
unsigned short usCPU_ADC_Battery;
unsigned short usCPU_ADC_Aux;



void CPU_AD_SetChannel(unsigned char ucCh)
{
	adst = 0;
	adcon0 = 0x80 | ucCh;
	adst = 1;
}

unsigned short CPU_AD_GetValue(unsigned char ucCh)
{
	unsigned short ucVal;

	switch  (ucCh)
	{
		case AD_CH0:
			ucVal = ad0;
			break;
		case AD_CH1:
			ucVal = ad1;
			break;
		case AD_CH2:
			ucVal = ad2;
			break;
		case AD_CH3:
			ucVal = ad3;
			break;
		case AD_CH4:
			ucVal = ad4;
			break;
		case AD_CH5:
			ucVal = ad5;
			break;
		case AD_CH6:
			ucVal = ad6;
			break;
		case AD_CH7:
			ucVal = ad7;
			break;
	}
	
	return(ucVal & 0x03FF);
}

void CPU_ADC_SetBattery(void)
{
	CPU_AD_SetChannel(AD_BAT);
}

unsigned short CPU_ADC_GetBatteryLevel(void)
{
	unsigned short i;
#if  1
	CPU_AD_SetChannel(AD_BAT);
	i = 0;
	while(1)
	{
		if  (adst == 0)
		{
			usCPU_ADC_Battery = CPU_AD_GetValue(AD_BAT);
			break;
		}
		if  (++i > 2000)
		{
			break;
		}
	}
#endif
	return(1);
}

unsigned short CPU_ADC_GetRemoconLevel(void)
{
	unsigned short i;
	unsigned short ucRet = 0xFFFF;
	
	CPU_AD_SetChannel(AD_RMC);
	i = 0;
	while(1)
	{
	#ifdef  R32C_118
		if  (adst_ad0con0 == 0)
	#endif
	#if  defined(M16C_30PG) || defined(M16C_64G)
		if  (adst == 0)
	#endif
		{
			ucRet = CPU_AD_GetValue(AD_RMC);
			break;
		}
		if  (++i > 2000)
		{
			break;
		}
	}
	
	return(ucRet);
}

void CPU_ADC_GetValue(void)
{	
	unsigned short i;

#if  0
	CPU_AD_SetChannel(AD_RMC);
	i = 0;
	while(1)
	{
		if  (adst == 0)
		{
			usCPU_ADC_Rmc = CPU_AD_GetValue(AD_RMC);	// Handle
		//	LOG_ACC("usCPU_ADC_Rmc:%d",usCPU_ADC_Rmc);
			break;
		}
		if  (++i > 2000)
		{
			break;
		}
	}
#endif
#if  0
	CPU_AD_SetChannel(AD_BAT);
	i = 0;
	while(1)
	{
		if  (adst == 0)
		{
			usCPU_ADC_Battery = CPU_AD_GetValue(AD_BAT);
			break;
		}
		if  (++i > 2000)
		{
			break;
		}
	}
#endif

	CPU_AD_SetChannel(AD_AUX);
	i = 0;
	while(1)
	{
		if  (adst == 0)
		{
			usCPU_ADC_Aux = CPU_AD_GetValue(AD_AUX);
			break;
		}
		if  (++i > 2000)
		{
			break;
		}
	}
}

void CPU_SetADC(void)
{
	#ifdef  M16C_64G

	adcon0 = 0x80;
	adcon1 = 0x20;
	adcon2 = 0x06;
		
	#endif

	#ifdef M16C_30PG

	adcon0 = 0x80;
	adcon1 = 0x28;
	adcon2 = 0x00;	
//	adcon1 = 0x20;
//	adcon2 = 0x06;

	#endif

}

/*///////////////////////////////////////////////////////////////////
Title : void CPU_SetPort(void)
****. Direction Register Default is ALL 0x00 ( Input )
///////////////////////////////////////////////////////////////////*/
void CPU_SetPort(void)
{
#ifdef  MODEL_AGC5030

	pd10 = 0x22; // BIN_0010_0110
				// PO_MOTOR : Defulat is Input, share whith LC786XXX
	prcr = 0x04;
	pd9 = 0x7F;	// BIN_0111_1111
	pd8 = 0x01;	// BIN_0000_0001
	pd7 = 0x7D;	// BIN_0111_1101

	pd6 = pd6 & 0xF0;	 
	pd6 = pd6 | 0x0A | 0x01;	// BIN_0000_1010  
	
	pd5 = pd5 & 0x21;
	pd5 = 0x04;	// BIN_0000_0100
	pd4 = 0xBF;	// BIN_1110_0100

	pd3 = 0x04;
	pd2 = 0x03;	// BIN_0000_0011
//	pu04 = 1;
	pd1 = 0x9B;	// BIN_1000_1011
	pd0 = 0xA0; // BIN_1010_0000

	p10 = 0x00;
	p9 = 0x00;
	p8 = 0x00;
#ifdef  NXP
	p8 = p8 | 0x01;
#endif
	p7 = 0x00;
#ifdef  NXP
	p7 = p7 | 0x40;
#endif

	p6 = p6 & 0xF0;
	
	p5 = 0x00;
	p4 = 0x00;
	p2 = 0x01;	// Mute On
	p1 = 0x00;
	p0 = 0x00;
	
	p4 = p4 | 0x10;	// EEPROM CS High
	pu11 = 1;	// Pull-Up For eeprom
	PO_SF_WP = 1;
#endif

#ifdef  MODEL_AGC505X

	pd10 = 0x22; // BIN_0010_0110
				// PO_MOTOR : Defulat is Input, share whith LC786XXX
	prcr = 0x04;
	pd9 = 0x7F;	// BIN_0111_1111
	pd8 = 0x01;	// BIN_0000_0001
	pd7 = 0x6D;	// BIN_0111_1101

	pd6 = pd6 & 0xF0;	 
	pd6 = pd6 | 0x0A | 0x01;	// BIN_0000_1010  
	
	pd5 = pd5 & 0x21;
	pd5 = 0x04;	// BIN_0000_0100
	pd4 = 0xBF;	// BIN_1110_0100

	pd3 = 0xC4;
	pd2 = 0x03 | 0x10;	// BIN_0000_0011
//	pu04 = 1;
	pd1 = 0xFB;	// BIN_1000_1011
	pd0 = 0xA0; // BIN_1010_0000

	p10 = 0x00;
	p9 = 0x00;
	p8 = 0x00;
	p7 = 0x00;

	p6 = p6 & 0xF0;
	
	p5 = 0x00;
	p4 = 0x00;
	p2 = 0x01;	// Mute On
	p1 = 0x00;
	p0 = 0x00;
	
	p4 = p4 | 0x10;	// EEPROM CS High
	pu11 = 1;	// Pull-Up For eeprom
	PO_SF_WP = 1;

	#ifdef  NXP
	PD_NXP_SCL = 1;
	PD_NXP_SDA = 1;
	PO_NXP_SCL = 1;
	PO_NXP_SDA = 1;
	#endif
#endif

#ifdef  MODEL_ARA5040	// Under is MODEL_ARA5040

	pd10 = 0x00;
	prcr = 0x04;
	pd9 = 0x0F;
	pd7 = 0x3D;	// 0011 1101

	pd5 = pd5 & 0x21;
	pd5 = pd5 | 0x04;

	pd6 = pd6 & 0xF0;	// For E8A
	pd6 = pd6 | 0x0B;	// For E8A
	pd4 = 0xC3;	// 0xC3

	pd3 = 0x80;
	pd2 = 0x23;
//	pu04 = 1;
	pd1 = 0x22; 
	pd0 = 0x20;

	p2 = (p2 & 0xFD) | 0x01;	//p2 | 0x01;		// For Mute
#endif
	prc2 = 0;
}

void CPU_SetTimer(void)
{		
/////////////// Timer A0 : 5msec /////////////////
/////////////// Main Clock 16MHz ////////////////
	ta0mr = 0x00;
	tck1_ta0mr = 1;		// f32TIMAB
	tck0_ta0mr = 0;
#ifdef	M16C_64G
	ta0 = 3750 - 1; 
#else
	ta0 = 2500 - 1;// 5msec = 5000usec = (n - 1) * 5usec
						// 5 usec = f(1/32)MHz
#endif	
	ta0ic = 2;			// Interrupt level 2
	ir_ta0ic = 0;		// Interrupt not requested

	ta0s = 1;	// Timer A0 count start flag

	
/////////////// Timer A1 : 1 sec //////////////////
#ifdef  OPTIONAL_CLOCK
	if  (OPT_GetOption(OPT_MASK_CLOCK) == 1)
#endif
	{
		ta1mr = 0xC0;	// Count Source Select : fc32 ( Sub clock )
		ta1 = 1024 - 1;	// (32.768 KHz / 32) = 1.024 KHz = 1024 Hz => (1/1024) sec

		ta1ic = 1;			// Interrupt Level 1
		ir_ta1ic = 1;		// Interrupt not requested
		
		ta1s = 1;	// Timer A1 count start flag
	}
	ta2mr = 0x37;
	ta2= 33054;  
//ta2s = 1;
//ucTa_ii = 1;
}

void CPU_SetSerial(void)
{
#ifdef  BLUETOOTH
/////////////// UART0 : Bluetooth Movon ///////////////
	/* ==== UART1 initialize ==== */
	u0c1  = 0x00;	/* Transmission disabled */
					/* Reception disabled */
	u0mr = 0x05;	/* UART mode character bit length is 8 bits */
					/* Internal/external clock: Internal clock */
					/* Stop bit length: 1 stop bit */
					/* Parity disabled */
					/* TXD, RXD I/O polarity inverse: Not inverted */

	u0c0 = 0x10;	/* U1BRG count source: f1SIO */
					/* CTS/RTS function disabled */
					/* Data output: Pins TXDi/SDAi and SCLi are CMOS output */
					/* Bit order: LSB first */
	u0c1 = 0x00;	/* Data logic: No reverse */
					/* Error signal output: Output disabled */
	u0irs = 0;		/* Transmission buffer empty */
					/* causes UART1 transmit interrupt */
					
	u0rrm = 0;
	clkmd0 = 0;
	rcsp = 0;

	u0brg = 38;			/* 38462*/
			//155;		/* 9600*/
	u0smr  = 0x00;	/* 00h is set the UART1 special mode register */
	u0smr2 = 0x00;	/* 00h is set the UART1 special mode register 2 */
	u0smr3 = 0x00;	/* 00h is set the UART1 special mode register 3 */
	u0smr4 = 0x00;	/* 00h is set the UART1 special mode register 4 */
	s0tic = 0x01;	/* UART1 transmit Interrupt: Level 1 */
	s0ric = 0x02;	/* UART1 receive Interrupt : Level 2 */
	u0c1  = 0x05;	/* Transmission enabled */
					/* Reception enabled */
	u0bcnic = 0x02;
	////////////////////////////////////////////////////
#endif

#ifdef  DEBUG_UART
#ifdef	M16C_64G
	/////////////// UART6 : Debug Uart  ///////////////
	/* ==== UART1 initialize ==== */
	u6c1  = 0x00;	/* Transmission disabled */
	                /* Reception disabled */
	u6mr = 0x05;	/* UART mode character bit length is 8 bits */
	                /* Internal/external clock: Internal clock */
	                /* Stop bit length: 1 stop bit */
	                /* Parity disabled */
	                /* TXD, RXD I/O polarity inverse: Not inverted */
	u6c0 = 0x10;	/* U6BRG count source: f1SIO */
	                /* CTS/RTS function disabled */
	                /* Data output: Pins TXDi/SDAi and SCLi are CMOS output */
	                /* Bit order: LSB first */
	u6c1 = 0x08;	/* Data logic: No reverse */
	                /* Error signal output: Output disabled */
	ucon = 0x00;	/* Transmission buffer empty */
	                /* causes UART6 transmit interrupt */
	u6brg = 38;			/* 38462*/
	u6smr  = 0x00;	/* 00h is set the UART6 special mode register */
	u6smr2 = 0x00;	/* 00h is set the UART6 special mode register 2 */
	u6smr3 = 0x00;	/* 00h is set the UART6 special mode register 3 */
	u6smr4 = 0x00;	/* 00h is set the UART6 special mode register 4 */
	s6tic = 0x07;	/* UART6 transmit Interrupt: Level 7 */
	s6ric = 0x06;	/* UART6 receive Interrupt : Level 6 */
	u6c1  = 0x05;	/* Transmission enabled */
					/* Reception enabled */
	////////////////////////////////////////////////////
#endif

#ifdef	M16C_30PG
	/////////////// UART6 : Debug Uart  ///////////////
	/* ==== UART1 initialize ==== */
	u1c1  = 0x00;	/* Transmission disabled */
	                /* Reception disabled */
	u1mr = 0x05;	/* UART mode character bit length is 8 bits */
	                /* Internal/external clock: Internal clock */
	                /* Stop bit length: 1 stop bit */
	                /* Parity disabled */
	                /* TXD, RXD I/O polarity inverse: Not inverted */
	u1c0 = 0x10;	/* U6BRG count source: f1SIO */
	                /* CTS/RTS function disabled */
	                /* Data output: Pins TXDi/SDAi and SCLi are CMOS output */
	                /* Bit order: LSB first */
	u1c1 = 0x08;	/* Data logic: No reverse */
	                /* Error signal output: Output disabled */
	ucon = 0x00;	/* Transmission buffer empty */
	                /* causes UART6 transmit interrupt */
	u1brg = 25;		/*  38400 bps */
	u1smr  = 0x00;	/* 00h is set the UART6 special mode register */
	u1smr2 = 0x00;	/* 00h is set the UART6 special mode register 2 */
	u1smr3 = 0x00;	/* 00h is set the UART6 special mode register 3 */
	u1smr4 = 0x00;	/* 00h is set the UART6 special mode register 4 */
	s1tic = 0x07;	/* UART6 transmit Interrupt: Level 7 */
	s1ric = 0x06;	/* UART6 receive Interrupt : Level 6 */
	u1c1  = 0x05;	/* Transmission enabled */
					/* Reception enabled */
	////////////////////////////////////////////////////
#endif

#endif

#ifdef  SERIAL_FLASH
///////////////////////////// Serial 7 : EEPROM  /////////////////////////////////
	u7mr = 0x01;	// Serial I/O mode select bit[0,1,2] : (001) Clock synchronous serial I/O mode
	u7c0 = 0x90;//0x99;	// UiBRG count source select bit [0,1] : (01) f8SIO is selected
					// Transmit register empty flag[3] : (1) No data present in transmit register(transmission completed)
					// Transfer format select bit[7] : (1) MSB First
	u7brg = 40;//25;//80; 25 ->40 24MHz
	u7c1 = 0x10;//0x10;
	u7smr2 = 0x00;
	u7smr3 = 0x00 | 0x02;
	u7smr4 = 0x00;
//	te_u7c1 = 1;
//	re_u7c1 = 1;
//	s7tic = 0x05;	/* Set SIO7 interrupt priority-level = 5	*/
//	ucon ????
//////////////////////////////////////////////////////////////////////////////

#endif
}

void CPU_SetIntrrupt(void)
{	
#ifdef  M16C_64G
///////////// INT0 (CD Eject Key) ////////////////////
	int0ic = 0x07;		// Level 7
///////////////////////////////////////////////////

///////////// INT1 (BackUp) ////////////////////
	int1ic = 0x04;
///////////////////////////////////////////////////

///////////// INT2 (ACC) ////////////////////
//	int2ic = 0x03;
///////////////////////////////////////////////////
#endif
}

void CPU_SetDMAC(void)
{	
#if defined(ST7565P) || defined(PT6524)
/////////////////////// DMA :Serial2(ST7565) ////////////////////////
	dm0sl = 0x0c;	// DMA request source select bit[0,1,2,3,4] : UART2 transmission
					// Software DMA request bit[8] : 
	dm0con = 0x11;

	/* Set DMA0 Destination pointer address */
	dar0_addr.byte.low  = (char)(&u2tb);
	dar0_addr.byte.mid  = (char)((unsigned long)(&u2tb) >> 8);
	dar0_addr.byte.high = (char)((unsigned long)(&u2tb) >> 16);

	dm0ic = 7;	/* Set DMA0 interrupt priority-level = 7	*/
//////////////////////////////////////////////////////////////////
#endif
}

void CPU_Initialize(void)
{
	unsigned int i;
#ifdef  M16C_64G
	prcr = 0x03;	// CM0,CM1,CM2,PLC0,PCLKR,FRA0 register protect off
					// PM0,PM1,PM2,TB2SC,INVC0,INVC1 register protect off
	pm0 = 0x00;		// Processor mode: Single-chip mode */ -> All pins are I/O ports or peripheral function I/O pins
	pm1 = 0x08;		// Watchdog timer function: Watchdog timer interrupt
					// Internal reserved area: The entire area usable
					// Wait: No wait state
	cm2 = 0x00;		// System clock select: Main clock

	cm1 = 0x00		// Main clock division select: No division mode
		| 0x00		// XIN-OUT drive capacity : Low
		| 0x10		// 125 kHz on-chip oscillator stop : Off
		| 0x00;		// etc...
	cm0 = 0x18;		// Main clock division select: CM16 and CM17 enabled
	cm07 = 0;
	pm20  = 1;		// SFR 1wait when PLL on
	plc0  = 0x23;	// PLL clock Multiply by 4
					//PLL multiplying factor select: Multiply by 8
				 	// Reference frequency counter: Divide by 2
	plc07 = 1;					 // PLL operation enable: PLL ON
	for (i = 0; i < 20000; i++); // Wait until the PLL clock becomes stable (tsu(PLL))
	cm11  = 1;					 // System clock select: PLL clock
	prcr = 0x00;

#endif
#ifdef M16C_30PG

	prcr = 0x01;
	pm0 = 0x40;

	cm05 = 0;
	cm07 = 0;
	cm15 = 1;	
	cm03 = 1;
	cm06 = 0;
	cm04 = 1;
	prcr = 0x00;

#endif
	CPU_SetTimer();
	CPU_SetPort();
	CPU_SetSerial();
	CPU_SetIntrrupt();
	CPU_SetDMAC();
	CPU_SetADC();
#ifdef  DEBUG_UART
	UART6_ResetBuf();
#endif
}

#ifdef  USER_WATCHDOG
unsigned char ucCPU_WatchDogEnable;
unsigned char ucCPU_WatchDog_Timer50msec;

void CPU_WatchDogEnable(void)
{
	ucCPU_WatchDogEnable = 1;
	ucCPU_WatchDog_Timer50msec = 3000 / 50;
	PO_MUTE = 1;
}

void CPU_WatchDogMain(void)
{
	if  (ucCPU_WatchDogEnable == 0)
	{
		return;
	}

	if  (ucCPU_WatchDog_Timer50msec == 0)
	{
	#ifdef  M16C_64G
		wdtr = 0xFF;
		prcr = 0x30;
		pm12 = 1;
		prcr = 0x00;
		wdts = 1;
	#endif
	#ifdef  M16C_30PG
		prc1 = 1; /* Write enabled */ 
		pm12 = 1; /* Watchdog timer function is selected to "Watchdog timer reset" */ 
		prc1 = 0; /* Write protected */ 
		wdts = 1; /* Set watchdog timer start register */
	#endif
		while(1)
		{
		}
	}
}
#endif

